public Class ContactEmailTriggerHandler{

static Set<Id> conemailupdateid=new Set<Id>();
static Set<Id> conemailinsertid=new Set<Id>();

public void ContactEmailInsert(List<Contact_Email__c> conemaillist){
     Set<Id> emailid=new Set<Id>();
     Set<Id> conid=new Set<Id>();
    List<Contact_Email__c> oldcontactemaillist=new List<Contact_Email__c>();
    List<Contact_Email__c> oldcontactemailupdatelist=new List<Contact_Email__c>();
    Contact_Email__c email=new Contact_Email__c();
    
    if(conemaillist!=null&&conemaillist.size()>0){ 
     email=conemaillist[0];
        for(Contact_Email__c conemail: conemaillist){
            emailid.add(conemail.Id);
            conid.add(conemail.Contact__c);
        }       
        oldcontactemaillist=[select Contact__c,Preferred__c from Contact_Email__c where Preferred__c=true AND Contact__c IN:conid AND Id NOT IN:emailid];
        
    for(Contact_Email__c conemail: conemaillist){
                      
            system.debug('&&oldcontactemaillist'+ oldcontactemaillist);
            system.debug('&&conemaillist'+ conemaillist);
            if(oldcontactemaillist!=null && oldcontactemaillist.size()>0){                 
                      
                   if(conemail.Preferred__c==true) {      
                    for(Contact_Email__c oldaddress : oldcontactemaillist){
                             oldaddress.Preferred__c=false;
                             oldcontactemailupdatelist.add(oldaddress);
                             conemailinsertid.add(oldaddress.Id);       
                    }
                  }
                    
            }else{
                email.Preferred__c=true;
            }                             
        }
        
        system.debug('&&oldcontactemailupdatelist'+ oldcontactemailupdatelist);
      if(!oldcontactemailupdatelist.IsEmpty()){
          update oldcontactemailupdatelist;
      }
    
    }
    
 }
public void ContactEmailUpdate(List<Contact_Email__c> newconemaillist,List<Contact_Email__c> oldconemaillist){
     Set<Id> emailid=new Set<Id>();
     Set<Id> conid=new Set<Id>();
    List<Contact_Email__c> oldcontactemaillist=new List<Contact_Email__c>();
    List<Contact_Email__c> oldcontactemailupdatelist=new List<Contact_Email__c>();
    
    if(newconemaillist!=null&&newconemaillist.size()>0){    
        for(Contact_Email__c conemail: newconemaillist){
            emailid.add(conemail.Id);
            conid.add(conemail.Contact__c);
        }       
        oldcontactemaillist=[select Contact__c,Preferred__c from Contact_Email__c where Preferred__c=true AND Contact__c IN:conid AND Id NOT IN:emailid];
        
   
            for(Contact_Email__c newconemail: newconemaillist){
                for(Contact_Email__c oldconemail: oldconemaillist){
                    if((newconemail.Preferred__c==true && oldconemail.Preferred__c==false && newconemail.Contact__c==oldconemail.Contact__c)){ 
                        for(Contact_Email__c accvalue: oldcontactemaillist){
                              accvalue.Preferred__c=false;        
                              oldcontactemailupdatelist.add(accvalue);
                              conemailupdateid.add(accvalue.Id);                            
                          } 
                    } else{
                    for(Contact_Email__c conval: newconemaillist){
                          
                            if(conemailupdateid.contains(conval.id) ){
                            }else{
                            if(conemailinsertid.IsEmpty()&&(newconemail.Preferred__c==false&& oldconemail.Preferred__c==true))
                             trigger.new[0].addError('cannot update');  
                            }
                        }
                    
                    }
                
                }
            }
           
        }
        
        if(!oldcontactemailupdatelist.isEmpty()){
                try{
                    
                    update oldcontactemailupdatelist;
                }catch(Exception e){
                    system.debug('# Exception while updating : '+e);
                }
            }                                  
    }
    public void ContactEmailDelete(List<Contact_Email__c> contactemaillist){
        if(contactemaillist!=null&&contactemaillist.size()>0){
            system.debug('@@accountemaillist '+contactemaillist);
            for(Contact_Email__c conemail: contactemaillist){
            
            if(conemail.Preferred__c==true){
                    trigger.old[0].addError('Cannot delete prefered record');  
                }
            }
        
        }

    }
    
/************************************************************************
        Purpose     : Test Class                  
        Parameters  : None
        Returns     : None
***********************************************************************/
    @isTest(SeeAllData=false)
     static public void testContactEmailTriggerHandler() {
         PIMS_Reserved_Id__c pimsid=new PIMS_Reserved_Id__c();
         pimsid.PIMS_Id__c='0000-0000';
         pimsid.Used__c=false;
         insert pimsid;
         
         PIMS_Reserved_Id__c pimsid1=new PIMS_Reserved_Id__c();
         pimsid1.PIMS_Id__c='0001-0000';
         pimsid1.Used__c=false;
         insert pimsid1;
        
         Account acc=new Account();
         acc.Name='test';
         acc.Type='SSO';
         insert acc;
         
         
         Contact con=new Contact();
         con.LastName='Test';
         con.AccountId=acc.id;
         con.Status__c='Active';
         con.Affiliate_Organizational_Role__c='test';
         con.Gender__c='Male';
         insert con;
         
         Contact_Email__c contactemail=new Contact_Email__c();
         contactemail.Contact__c=con.id;
         contactemail.Email_Type__c='Email at Home';
         contactemail.Email__c='Test@a.com';
         contactemail.Preferred__c=true;
         insert contactemail;
         update contactemail;
         
         Contact_Email__c contactemail0=new Contact_Email__c();
         contactemail0.Contact__c=con.id;
         contactemail0.Email_Type__c='Email at Home';
         contactemail0.Email__c='Test@a.com';
         contactemail0.Preferred__c=false;
         insert contactemail0;
         contactemail0.Preferred__c=true;
         update contactemail0;
         
         Contact_Email__c contactemail1=new Contact_Email__c();
         contactemail1.Contact__c=con.id;
         contactemail1.Email_Type__c='Email at Home';
         contactemail1.Email__c='Test@a.com';
         contactemail1.Preferred__c=false;
         insert contactemail1;
         delete contactemail1;
         
     
     }   
}